package com.zhudi.develop_demo_as.network;

import android.content.Context;
import android.os.Handler;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestHandle;
import com.loopj.android.http.RequestParams;
import com.zhudi.develop.util.ZhudiSystemInfoUtil;
import com.zhudi.develop_demo_as.JsonObjectParser;
import com.zhudi.develop_demo_as.widget.DialogCancelInterface;
import com.zhudi.develop_demo_as.widget.ProgressHUD;

import org.apache.http.Header;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by zhudi on 2015/9/14.
 * 网络请求服务
 */
public class NetworkService<T> {
	private List<RequestHandle> requestHandles = new ArrayList<RequestHandle>();
	private JsonObjectParser jsonParser = null;
	private static final String BEAN_PACKAGE_PATH = "com.vastrek.geelyhelper.databean.";
	private String mActionId;
	/**设置超时时间 */
	public static final int TIMEOUT = 3000;
	/**数据解析错误码 */
	public static final int ERRORJSON_CODO = 0x3FFF;
	/**数据解析错误提示内容 */
	private static final String ERRORJSON_MSG = "数据解析错误";


	private NetworkListener<T> listener;
	/**是否显示遮罩层 */
	private boolean needValidate = true;
	private ProgressHUD pd;
	private Handler handler;
	private Context mContext;

	public NetworkService(String actionId, NetworkListener<T> listener) {
		mActionId = actionId;
		this.listener = listener;
		handler = new Handler();
	}

	// 公有方法-------------------------------------------------------------------------------------------
	public interface NetworkListener<T> {
		void onReceiveResult(T result);
		void onFailure(int code, String msg);
	}


	public void configNeedValidate(boolean b) {
		needValidate = b;
	}

	public void configAnalyze(JsonObjectParser jsonParser){
		this.jsonParser = jsonParser;
	}

	public void configContext(Context context) {
		mContext = context;
	}


	/**
	 * post提交
	 *
	 * @param params
	 */
	public void postSubmit(String url,RequestParams params) {
		send(url, params);
	}

	/**
	 * get提交
	 */
	public void getSubmit(String url) {
		send(url, null);
	}

	public void getObjectFromString(String result) {
		handleBaseResult(result);
	}

	// ~ 私有方法
	// -------------------------------------------------------------------------------------
	private void send(String url,RequestParams params) {
		// 判断网络是否连接
		if (!ZhudiSystemInfoUtil.checkNetWorkStatus(mContext)) {
			//ZhudiToastSingle.showToast(this, R.string.data_load_fail, false);
			return;
		}
		if (url == null){
			//ZhudiToastSingle.showToast(this, R.string.data_load_fail, false);
			return;
		}
		if (needValidate) {
			//LoadingLayer.show();
			showLoadingDialog();
		}
		AsyncHttpClient client = new AsyncHttpClient();
		client.setTimeout(TIMEOUT);//20s
		RequestHandle rh = null;
		if (params == null){
			rh = client.get(mContext,url, new AsyncHttpResponseHandler() {
				@Override
				public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
					handleBaseResult(new String(responseBody));
				}

				@Override
				public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable exception) {
					failureResult(statusCode, exception);
				}

				@Override
				public void onFinish() {
					//LoadingLayer.hide();
					dismissPd();
				}
			});
		} else {
			rh = client.post(mContext, url, params,new AsyncHttpResponseHandler() {
				@Override
				public void onSuccess ( int statusCode, Header[] headers,byte[] responseBody){
					handleBaseResult(new String(responseBody));
				}

				@Override
				public void onFailure ( int statusCode, Header[] headers,
				byte[] responseBody, Throwable exception){
					failureResult(statusCode, exception);
				}


				@Override
				public void onFinish () {
					//LoadingLayer.hide();
					dismissPd();
				}
			});
		}
		requestHandles.add(rh);
	}

	/**
	 * 处理错误的返回
	 * @param statusCode
	 * @param exception
	 */
	private void failureResult(int statusCode, Throwable exception) {
		int exceptionCode = statusCode;
		Throwable cause = exception.getCause();
		String errorMessage = "";
		if (cause instanceof ConnectTimeoutException) {
			errorMessage = "服务器请求超时!";
		} else if (cause instanceof HttpHostConnectException) {
			errorMessage = "服务器连接失败!";
		} else if (exceptionCode == 500) {
			errorMessage = "服务器内部错误!";
		} else if (exceptionCode == 404) {
			errorMessage = "连接地址未找到，请联系管理员检查服务是否启动!";
		} else if (cause instanceof IOException) {
			errorMessage = "IO异常,请检查主机IP是否正确!";
		}
		handleErrorResult(exceptionCode, errorMessage);
	}


	/**
	 * 处理返回字符串
	 *
	 * @param result
	 */
	private void handleBaseResult(String result) {
		try {
			JSONObject root = new JSONObject(result);
			if (root.getInt("status") == 200) {
				if (root.has("data")) {
					try {
						handleResultBody(root.getString("data"));
					} catch (Exception e) {
						e.printStackTrace();
						//数据解析错误
						handleErrorResult(ERRORJSON_CODO,ERRORJSON_MSG);
					}
				}
			} else {
				handleErrorResult(root.getInt("status"),root.getString("message"));
			}
		} catch (JSONException e) {
			e.printStackTrace();
			//数据解析错误
			handleErrorResult(ERRORJSON_CODO,ERRORJSON_MSG);
		}
	}


	/**
	 * 返回正确结果,进一步处理  TODOs
	 *
	 * @param data
	 */
	private void handleResultBody(String data) throws Exception {
		if (listener != null) {
			if (jsonParser != null)
			    listener.onReceiveResult((T)jsonParser.parse(data));
		}
	}

	/**
	 * 处理错误结果 TODOs
	 *
	 * @param code
	 * @param message
	 */
	private void handleErrorResult(int code, String message) {
		if (listener != null) {
			listener.onFailure(code, message);
		}
	}

	/**
	 * 显示加载Dialog
	 */
	private void showLoadingDialog() {
		pd = ProgressHUD.create(mContext)
				.setStyle(ProgressHUD.Style.SPIN_INDETERMINATE)
				.setLabel("请稍等")
				.setBackCancelListener(new DialogCancelInterface() {
					@Override
					public void backCancel() {
						System.out.println("MainActivity------>取消");
						dismissPd();
						cancelRequestAll();
					}
				})
				.setCancellable(true);
		pd.show();
	}


	/**
	 * 取消进度的显示
	 */
	private void dismissPd() {
		if (pd != null) {
			pd.dismiss();
			pd = null;
		}
	}

	/**
	 * 取消所有请求
	 */
	private void cancelRequestAll() {
		for (RequestHandle handle : requestHandles) {
			if (!handle.isCancelled() && !handle.isFinished()) {
				handle.cancel(true);
			}
		}
	}

}
